<?php
    
	namespace App\Models\Staff;

	use App\Func\AuthFunc;
    use App\Func\TokenFuc;
    use App\Models\Staff\cStaffRole;

	/* description	: staff permission control
	 * developer	: BREEZEER
	 * create		: 2022.05.13
	 *
																					+-------------------------------+
		+---------------------------------------------------------------------------|  staff permission design flow	|
		|																			+-------------------------------+
		|
		|
		|
		|
		|
		|
		|																				 -----------------> 1. 客户档案台账
		|																				/
		|												 ---------> 1. 客户管理--------<
		|				 ----+							/								\-----------------> 2. 信用客户管理
		|				/	 |-----> 1. 模块权限 ------<								|-----------------> 3. ....
		+---> 系统权限 <								\								+-----------------> 4. ....
		|				\								 +--------> 2. 信用项目管理---+
		|				 | 								 |							  |       ------------> 1. 信用项目台账
		|				 |  							 |							  |		 /
		|				 |								 |							  +-----<
		|				 |								 |									 \
		|				 |								 +--------> N. 						  |-----------> 2. 新建信用项目
		|			 	 |																	  |-----------> 3. 调减申请
		|				 |								 +-------> r=1						  |-----------> 4. 调增申请
		|			 	 |								/									  +-----------> 5. 信用项目详情
		|				 +--------> 2. 数据权限 -------<
		|												\
		|												 |
		|                                                +------> w=2
		|
		|
		|
		|
		|																       --------> 1. 客户管理
		|																      /
		|		      ------------------------------------> 1. 总管理员 -----<
		|		     /														  \
		+---> 角色	<														   |-------> 2. 信用项目管理
					 \														   |-------> 2. xxx
					 |														   |-------> 3. xxx
					 |														   |-------> 4. xxx
					 |														   |-------> 5. xxx
					 |														   |-------> 6. xxx
					 |														   |-------> 7. xxx
					 |														   +-------> 8. xxx
					 |-----------------------------------> 2. 财务管理 --------+
					 |													       |
					 |													       |---------> 1. 出纳
					 |													       +---------> 2. 会计
					 |
					 |-----------------------------------> 3. 信控专员 --------+
					 |														   |
					 |														   |---------> 1. 信用项目台账
					 |														   |---------> 2. 客户档案台账
					 |														   |---------> 3. 调减申请
					 |														   |---------> 4. 调增申请
					 |														   |---------> 5. 信用项目详情
					 |														   +---------> 6. 信用客户管理
					 |
					 |
					 |
					 |
					 |
					 |
					 +-----------------------------------> N. xxxx 角色 ------+
																			  |
																			  |---------> 1. xxx
																			  |---------> 2. xxx
																			  |---------> 3. xxx
																			  |---------> 4. xxx
																			  |---------> 5. xxx
																			  +---------> 6. xxx
	 * tips:	1. 必须明确系统内所有的模块
	 * 			2. 每一个模块功能对应后台左侧菜单导航节点
	 *			3. 如果子节点有查看功能,那么该子节点的所有父节点必须被罗列展示
	 *			4. 数据权限绑定在最末的叶子节点上 r=> 读 w=> 写【添加，修改，删除】
	 *
	 *
	 *




	 * 职员权限实现用到的数据库表
	 *
	 *
	 *
	 *
		1. cy_auth_auth		=> 系统所有权限列表（导航菜单的叶子节点或者其他特殊的权限名称）
																														1. 客户档案台账
																														2. 信用客户管理
																														3. 信用项目台账
																														4. 新增客户
																														5. 查看贸易型客户信用评价表
																														6. 出纳
																														7. 会计
																														N.


		2. cy_auth_menu		=> 完整的导航菜单树，菜单之间有上下级别的父子关系，当前职员能够查看哪些菜单，由该职员的权限决定
																														1. 客户管理
																														|
																														|
																														|------------------> 客户档案台账
																														|					 |
																														|					 |-----> 新增客户
																														|					 |-----> 新增客户
																														|					 |-----> 贸易型客户信用评价表
																														|					 |-----> .
																														|					 |-----> .
																														|					 |-----> .
																														|					 +-----> .
																														|
																														+------------------> 系统设置
																																			 |
																																			 |-----> 注销
																																			 +-----> 退出系统

		3. cy_auth_role		=> 角色包含的所有权限
																														1. 财务管理员会计
																														|
																														|-----------> 1. 出纳 (r	= 4)
																														+-----------> 2. 会计 (rw	= 6)

																														2. 信控专员
																														|
																														|---------> 1. 信用项目台账
																														|---------> 2. 新建信用项目
																														|---------> 3. 调减申请
																														|---------> 4. 调增申请
																														+---------> 5. 信用项目详情

																														3. 财务管理员出纳
																														|
																														|-----------> 1. 出纳 (rw	= 6)
																														+-----------> 2. 会计 (r	= 0)

																														4. 财务总监
																														|
																														|-----------> 1. 出纳 (r	= 4)
																														+-----------> 2. 会计 (r	= 4)

																														5.
																														6.
																														N.

		4. cy_role			=> 角色表
																														1. 财务管理员会计
																														2. 信控专员
																														3. 财务管理员出纳
																														4. 财务总监
																														5.
																														6.
																														N.


		5. cy_staff_role	=> 职员与角色的绑定关系
																														1. 周杰伦 (全部角色列表)
																														|
																														|-----------> 1. 财务管理员
																														|-----------> 2. 信控专员
																														|-----------> 3. .
																														|-----------> 4. .
																														|-----------> 5. .
																														|-----------> 6. .
																														+-----------> 7. .

																														2. 张学友
																														3. 伍佰
																														4.
																														5.
																														6.
																														N.

		6. cy_staff_auth	=> 职员拥有特殊权限（即：职员的权限获取不一定完全来源于角色，可以跳过角色直接赋权限给职员)
																														1. 周杰伦 （额外的权限）
																														|
																														|-----------> 1. 查看库存
																														|-----------> 1. 发货
																														+-----------> 1. 收货款

    *
    *
    *
	*/
	class cStaffPermissionException extends \Exception
	{
	}
	class cStaffPermission
	{
		public function __construct()
		{
			$this->m_helper				= app()->gcHelper	;
			$this->m_n_current_staff_id = 0					; # current staff id
		}
		public function setCurrentStaffID($nCurrentStaffID)
		{
			$this->m_n_current_staff_id	= $nCurrentStaffID	;
			return $this;
		}

		/* 获取职员的导航菜单
		 *
		 */
		public function getCurrentStaffNavigationMenu($callback_one_navigation_menu=null)
		{
			# 1. 获取职员的全部权限再过滤出菜单权限
			# 2. 菜单权限的数据位 = 1
			#
			#
			$menu_id = [];$this->getCurrentStaffAllPermission	(
																	function($one_permission) use(&$menu_id) 
																	{
																		if($one_permission->menu_id > 0/* it is menu permission */ && $one_permission->auth_value>0/* read enabled */ )
																		{
																			$menu_id[] = $one_permission->menu_id;
																		}
																	}
																);

			#
			#
			if(count($menu_id)==0)
			{
				return [];
			}
 
			# 构建菜单
			#
			#
			$o	= $this->m_helper->gfDbQuery()->buildSqlMultiParameter($menu_id);$o->thisx->select	
			(	
					"
						select * from ".$this->m_helper->gfGetTableNameByConstKey('CY_AUTH_MENU_TABLE_NAME')." where menu_id in(".$o->parameter.") 
					"
					,
					$o->thisx->mergeArrayMultiValueToSingle($o->value)->getLastSingleArray()
			)
			->forEachRow
			(
					function($row)
					{
						return $row->getOneRowAllData();
					}
					, 
					$ar
			);

			#
			#
			if($callback_one_navigation_menu==null)
			{
				return $ar['content'];
			}
			else
			{
				$callback_one_navigation_menu($ar['content']);
			}

			return $this; 
		}

		/* 获取职员全部的权限融合不同角色下的全部权限
		 *
		 */
		public function getCurrentStaffAllPermission($callback_one_permission=null) 
		{
			# 如果 m_n_current_staff_id > 0 那么就查看这个指定的职员，否则默认查看当前登录的职员
			#
			if( $this->m_n_current_staff_id > 0 )
			{
                // 修复公司ID默认值
				$ar		=	(new cStaffRole())->setStaffInfo(['company_id'=>66,'staff_id'=>$this->m_n_current_staff_id])->getAllAuth();
			}
			else
			{
				$ar		=	AuthFunc::getCurrentStaffAuth();
			}
			$arx		= [];

			# 从角色继承的权限

			#
			if(@is_array($ar['role_permission']))
			{
				foreach($ar['role_permission'] as $role_permission)
				{
					foreach($role_permission['mapRoleIdToAuthId'] as $one_permission)
					{
						$arx[] = $one_permission;
					}
				} 	
			}  

			# 从职员特殊权限表获取的权限
			#
			if(@is_array($ar['extra_permission']))
			{
				foreach( $ar['extra_permission'] as $one_permission)
				{
					$arx[] = $one_permission[0];
				} 
			}

			if(null==$callback_one_permission)
			{
				return $arx;
			}

			#
			#
			foreach($arx as $v){$callback_one_permission((object)$v);}

			return $this;
		}			
	}